package mdm.led.shiro;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;

import mdm.led.common.AjaxResponse;
import mdm.led.common.Constant;
import mdm.led.util.session.TokenSession;
import mdm.led.util.session.TokenSessionManager;
import mdm.led.util.session.TokenUtil;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
import java.util.Map;

/**
 * web请求拦截器 1)校验是否受保护的页面是否有登录token; 2)初始化身份信息; 3)功能权限校验;
 */
public class AuthWebFilter extends AccessControlFilter {
	private final static Logger LOGGER = LoggerFactory.getLogger(AuthWebFilter.class);

	private static final String zh_CN = "zh_CN";
	private static final String zh_HK = "zh_HK";
	private static final String en = "en";

	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
			throws Exception {
		LOGGER.info("come into AuthWebFilter.isAccessAllowed(),mappedValue=" + mappedValue);
		return false;
	}

	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
		LOGGER.info("come into AuthWebFilter.onAccessDenied()");

		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		String url = WebUtils.getRequestUri(httpRequest);
		LOGGER.info("this request url is>>" + url + httpRequest.getMethod());

		Map<String, String> chains = Maps.newHashMap();
		LOGGER.info("filter>>>" + httpRequest.getRequestURI().substring(httpRequest.getContextPath().length()));

		LOGGER.info("this request url method>>" + httpRequest.getMethod());

		chains.put("/", "anon");
		chains.put("/images", "anon");
		chains.put("/webjars", "anon");
		chains.put("/v2", "anon");
		chains.put("/login/", "anon");
		chains.put("/test", "anon");
		chains.put("/oauth", "anon");
		chains.put("/api", "anon");
		// 测试 暂时不做验证的模块
		chains.put("/ThreeCheck/pageApp", "anon");
		chains.put("/ThreeCheck/allUploadImages", "anon");
		chains.put("/ThreeCheck/modify", "anon");
		chains.put("/ThreeCheck/selectThreeCheckListApp", "anon");
		chains.put("/TrafficDanger/modify", "anon");
		chains.put("/TrafficDanger/pageApp", "anon");
		// chains.put("/ThreeCheck/exportExcel", "anon");
		chains.put("/ThreeCheck/pageContent", "anon");
		// chains.put("/TrafficDanger/exportExcel", "anon");
		chains.put("/user/addUserApp", "anon");
		chains.put("/user/modifyApp", "anon");
		chains.put("/department", "anon");

		// 测试 暂时不做验证的模块
		chains.put("/threeTableApp", "anon");
		chains.put("/threeTableWeb", "anon");
		chains.put("/user/addUserApp", "anon");
		chains.put("/user/modifyApp", "anon");
		chains.put("/department", "anon");
		chains.put("/user", "anon");

		chains.put("/dopeWeb", "anon");
		chains.put("/dopeApp", "anon");

		chains.put("/fiveProcedureWeb", "anon");
		chains.put("/fiveProcedureApp", "anon");

		chains.put("/fourInspectorWeb", "anon");
		chains.put("/fourInspectorApp", "anon");
		
		
		chains.put("/threeTaskExternalApp", "anon");

		for (String key : chains.keySet()) {
			if (url.contains(key)) {
				return true;
			}
		}
		LOGGER.info("===========1===========");
		Cookie[] cookies = httpRequest.getCookies();
		String lang = zh_CN;
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				if ("locale".equals(cookie.getName())) {
					lang = cookie.getValue();
				}
			}
		}
		if (en.equals(lang)) {
			LocaleContextHolder.setLocale(new Locale("en"));
		} else if (zh_HK.equals(lang)) {
			LocaleContextHolder.setLocale(new Locale("zh", "HK"));
		} else {
			LocaleContextHolder.setLocale(new Locale("zh", "CN"));
		}
		// 校验是否已经登录
		if (!checkLoginToken(httpRequest)) {
			writeResponseMsg(httpResponse, Constant.CHECK_LOGIN, "用户未登录");
			LOGGER.info("checkLoginToken(httpRequest)>>" + checkLoginToken(httpRequest));
			return false;
		}
		return true;
	}

	private void writeResponseMsg(HttpServletResponse httpResponse, int status, String msg) throws Exception {
		AjaxResponse ap = new AjaxResponse();
		ap.setMessage(msg);
		ap.setStatus(status);
		String rs = JSONObject.toJSONString(ap);
		httpResponse.setHeader("Cache-Control", "no-cache");
		httpResponse.setCharacterEncoding("UTF-8");
		httpResponse.setContentType("application/json; charset=utf-8");
		httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
		httpResponse.getOutputStream().write(rs.getBytes("UTF-8"));
	}

	/**
	 * 校验用户是否已经登录以及会话是否有效
	 */
	private boolean checkLoginToken(HttpServletRequest httpRequest) throws Exception {
		String token = httpRequest.getParameter("token");
		System.out.println("==============" + token);
		if (StringUtils.isEmpty(token)) {
			token = httpRequest.getHeader("token");
		}
		if (StringUtils.isEmpty(token)) {
			Cookie[] cookies = httpRequest.getCookies();
			if (cookies == null) {
				return false;
			}
			for (Cookie cookie : cookies) {
				if ("token".equals(cookie.getName())) {
					token = cookie.getValue();
				}
			}
		}

		LOGGER.info("token>>" + token);

		if (StringUtils.isEmpty(token)) {
			return false;
		} else {
			TokenSession ses = TokenSessionManager.getInstance().getDomainTokenSession(token);
			if (ses == null) {
				return false;
			} else {
				// 刷新会话
				ses.touch();
			}
		}
		return true;
	}

	/**
	 * 校验用户是否有资源访问权限
	 */
	private boolean checkAuthPermission(HttpServletRequest httpRequest) throws Exception {
		String uri = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length());
		if (uri.substring(uri.lastIndexOf("/") + 1).matches("[0-9]*")) {
			uri = uri.substring(0, uri.lastIndexOf("/") + 1);
		}
		LOGGER.info("--------------uri:{}", uri);
		LOGGER.info("----------user:{}----isPermitted:{}", TokenUtil.getUsername(TokenUtil.getToken(httpRequest)),
				SecurityUtils.getSubject().isPermitted(uri));

		return SecurityUtils.getSubject().isPermitted(uri);
	}

}
